package com.kpf.springcloud.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.kpf.springcloud.common.ResponseEnum;
import com.kpf.springcloud.exception.BusinessException;
import com.kpf.springcloud.mapper.TopicCollectMapper;
import com.kpf.springcloud.mapper.TopicCommentMapper;
import com.kpf.springcloud.pojo.*;
import com.kpf.springcloud.mapper.TopicMapper;
import com.kpf.springcloud.service.*;
import com.kpf.springcloud.utils.GeneralUtil;
import com.kpf.springcloud.utils.SortUtils;
import com.kpf.springcloud.vo.KpfTopicLikeAndCollectStatusVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author shiwen
 * @date 2021/3/1
 */
@Service
public class KpfTopicServiceImpl extends BaseServiceImpl<TopicMapper, KpfTopic> implements IKpfTopicService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private IKpfUserService kpfUserService;

    @Autowired
    private ITokenService tokenService;

    @Autowired
    private IKpfTopicCollectService topicCollectService;

    @Autowired
    private IKpfTopicLikeService topicLikeService;

    @Autowired
    private IKpfVisitTopicService kpfVisitTopicService;

    @Resource
    private TopicMapper topicMapper;

    @Resource
    private TopicCommentMapper topicCommentMapper;

    @Resource
    private TopicCollectMapper topicCollectMapper;

    @Override
    public PageResult getTopicList(int pageNum, int pageSize, String title) {
        Page page = PageHelper.startPage(pageNum, pageSize);
        List<KpfTopic> kpfTopicList = list(getInitQueryWrapper()
                .like(KpfTopic::getTitle, title)
                .eq(KpfTopic::getIsDelete, 0)
                .orderByDesc(KpfTopic::getSortNo));
        return new PageResult(kpfTopicList, page.getTotal(), pageNum, pageSize);
    }

    @Override
    public KpfTopic getById() {
        String kpfTopicId = stringRedisTemplate.opsForValue().get("kpfTopicId");
        // 访问人数动态 + 1
        kpfVisitTopicService.countVisitors(Integer.parseInt(kpfTopicId));
        return getOne(getInitQueryWrapper().eq(KpfTopic::getId, Integer.parseInt(kpfTopicId)).eq(KpfTopic::getIsDelete, 0));
    }

    @Override
    public void setTopicId(int topicId) {
        stringRedisTemplate.opsForValue().set("kpfTopicId", topicId + "");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editTopic(String title, String content, String topicMsg) {
        String token = tokenService.verifyToken();
        if ("TOKEN_EXPIRED".equals(token)) {
            throw new BusinessException(ResponseEnum.TOKEN_EXPIRED);
        }
        int userId = Integer.parseInt(token.split("-")[0]);
        KpfUser kpfUser = kpfUserService.getById(userId);
        KpfTopic kpfTopic = KpfTopic.builder().userId(userId).userName(kpfUser.getUsername()).userImg(kpfUser.getHeadimg())
                .topicMsg(topicMsg).title(title).content(content).isDelete(0L).build();
        save(kpfTopic);
    }

    /**
     * 根据帖子id和账号id判断点赞和收藏状态
     *
     * @param topicId
     * @return
     */
    @Override
    public KpfTopicLikeAndCollectStatusVO getAllStatusByTopicId(int topicId) {
        String token = tokenService.verifyToken();
        // 判断token是否过期
        if ("TOKEN_EXPIRED".equals(token)) {
            throw new BusinessException(ResponseEnum.TOKEN_EXPIRED);
        }
        int userId = Integer.parseInt(token.split("-")[0]);
        KpfTopicCollect topicCollect = topicCollectService.getOne(topicCollectService.getInitQueryWrapper()
                .eq(KpfTopicCollect::getTopicId, topicId).eq(KpfTopicCollect::getUserId, userId));
        KpfTopicLike topicLike = topicLikeService.getOne(topicLikeService.getInitQueryWrapper()
                .eq(KpfTopicLike::getTopicId, topicId).eq(KpfTopicLike::getUserId, userId));
        KpfTopicLikeAndCollectStatusVO kpfTopicLikeAndCollectStatusVO = new KpfTopicLikeAndCollectStatusVO();
        kpfTopicLikeAndCollectStatusVO.setCollectStatus(GeneralUtil.isObjNotNull(topicCollect)
                && topicCollect.getCollectStatus() == 1 ? 1 : 0);
        kpfTopicLikeAndCollectStatusVO.setLikeStatus(GeneralUtil.isObjNotNull(topicLike)
                && topicLike.getLikeStatus() == 1 ? 1 : 0);
        return kpfTopicLikeAndCollectStatusVO;
    }

    /**
     * 根据用户id获取所有的帖子内容
     */
    @Override
    public List<KpfTopic> getTopicListByUserId() {
        String userId = stringRedisTemplate.opsForValue().get("kpf:selfUserId");
        List<KpfTopic> kpfTopicList = new ArrayList<>();
        if (GeneralUtil.isNotNullAndEmpty(userId)) {
            kpfTopicList = list(getInitQueryWrapper().eq(KpfTopic::getUserId, userId));
            return kpfTopicList;
        }
        return kpfTopicList;
    }

    /**
     * 根据帖子id判断是否
     *
     * @param topicId
     */
    @Override
    public void deleteTopicById(int topicId) {
        String token = tokenService.verifyToken();
        // 判断token是否过期
        if ("TOKEN_EXPIRED".equals(token)) {
            throw new BusinessException(ResponseEnum.TOKEN_EXPIRED);
        }
        // 用户id
        int userId = Integer.parseInt(token.split("-")[0]);
        // 角色类型
        int roleType = Integer.parseInt(token.split("-")[1]);
        // 管理员角色的type = 2
        if (roleType == 2) {
            topicMapper.deleteById(topicId);
            // 删除帖子的时候其相对应的所有评论都要删除
            topicCommentMapper.deleteByTopicId(topicId);
            // 删除帖子时还要同时删除收藏列表的帖子
            topicCollectMapper.delete(topicCollectService.getInitQueryWrapper().eq(KpfTopicCollect::getTopicId, topicId));
            logger.info("Processing delete topic success！userId = {} , topicId = {}", userId, topicId);
        } else {
            throw new BusinessException(ResponseEnum.NOT_ADMIN_USER_TO_OPERA);
        }
    }

    /**
     * 初始化帖子权重
     */
    @Override
    public void initTopicSortNo() {
        List<KpfTopic> kpfTopicList = list();
        kpfTopicList.forEach(s -> {
            int sortNo = SortUtils.countSortNo(s);
            // 每两分钟更新一次权重值
            update(getLambdaUpdateWrapper().set(KpfTopic::getSortNo, sortNo).eq(KpfTopic::getId, s.getId()));
            logger.info("Processing update topicSortNo success！id = {} , oldSortNo = {} , newSortNo = {}",
                    s.getId(), s.getSortNo(), sortNo);
        });
    }

    @Override
    public void initTopicVisitData() {
        List<KpfTopic> kpfTopicList = list();
        kpfTopicList.forEach(s -> {
            int visitNum = kpfVisitTopicService.count(kpfVisitTopicService.getInitQueryWrapper().eq(KpfVisitTopic::getTopicId, s.getId()));
            // 每一分钟更新一次帖子阅读量
            update(getLambdaUpdateWrapper().set(KpfTopic::getVisitNum, visitNum).eq(KpfTopic::getId, s.getId()));
            logger.info("Processing update visitData success！id = {} , oldVisitNum = {} , newVisitNum = {}",
                    s.getId(), s.getVisitNum(), visitNum);
        });
    }

}